import request from "../framework/common/utils/request.js";
import {common} from "./common.js"
//operator.js
//calculator.js
//parser.js
//converter.js

var calculateExpression = {
    operators: {//operator.js
        0:"eq",1:"eq".toUpperCase(),
        2:"ne",3:"ne".toUpperCase(),
        4:"notlike",5:"notlike".toUpperCase(),
        6:"like",7:"like".toUpperCase(),
        8:"beginwith",9:"beginwith".toUpperCase(),
        10:"notnull",11:"notnull".toUpperCase(),
        12:"isnull",13:"isnull".toUpperCase(),
        14:"gt",15:"gt".toUpperCase(),
        16:"ge",17:"ge".toUpperCase(),
        18:"lt",19:"lt".toUpperCase(),
        20:"le",21:"le".toUpperCase(),
        22:"eqdate",23:"eqdate".toUpperCase(),
        24:"nedate",25:"nedate".toUpperCase(),
        26:"gtdate",27:"gtdate".toUpperCase(),
        28:"gedate",29:"gedate".toUpperCase(),
        30:"ltdate",31:"ltdate".toUpperCase(),
        32:"ledate",33:"ledate".toUpperCase(),
        34:"eqperson",35:"eqperson".toUpperCase(),
        36:"neperson",37:"neperson".toUpperCase(),
        38:"eqorg",39:"eqorg".toUpperCase(),
        40:"neorg",41:"neorg".toUpperCase(),
        42:"notlikeorg",43:"notlikeorg".toUpperCase(),
        44:"likeorg",45:"likeorg".toUpperCase(),
        46:"eqcity",47:"eqcity".toUpperCase(),
        48:"necity",49:"necity".toUpperCase(),
        50:"apieval",51:"apieval".toUpperCase(),
        52:"cnmoney",53:"cnmoney".toUpperCase(),
        54:"notnullcity",55:"notnullcity".toUpperCase(),
        56:"isnullcity",57:"isnullcity".toUpperCase(),
        58:"min",59:"min".toUpperCase(),
        60:"round",61:"round".toUpperCase(),
        62:"sum",63:"sum".toUpperCase(),
        64:"max",65:"max".toUpperCase(),
        66:"if",67:"if".toUpperCase(),
        68:"datediff",69:"datediff".toUpperCase(),
        70:"parenthesis",71:"parenthesis".toUpperCase(),  
    },
    calculator: function(){//calculator.js
        var self = calculateExpression;
        var op = self.operator;
        var parse = function(expression){
            if(expression=="" || !expression) return "";
            var stack = new Array();
            var queue = new Array();
            var expArr = expression.split("");
            var oprs = self.operators;
            var i = 0;
            while(expArr.length>0){
                stack.push(expArr.shift());
                for(var index in oprs){
                    var opName = oprs[index];
                    var match_rst = op[opName].match(stack);
                    var s_replacer = "expression_" + self.rndNum(5);
                    if(match_rst){
                        var v_match = match_rst.value;
                        stack.splice(stack.length-v_match.length,v_match.length);
                        stack.push(s_replacer);
                        var operatorStr =  match_rst.toString();
                        operatorStr = operatorStr.replace(/\$\#leftbracket\$\#/g,"(").replace(/\$\#rightbracket\$\#/g,")");
                        var operator = new op[opName]._class(operatorStr,s_replacer);
                        queue.push(operator);
                        i = i + 1;
                    }
                }
            }
            if(stack.length>0){
                var operatorStr2 =  stack.join("");
                operatorStr2 = operatorStr2.replace(/\$\#leftbracket\$\#/g,"(").replace(/\$\#rightbracket\$\#/g,")");
                var operator = new op[opName]._class(operatorStr2,"expression_end");
                queue.push(operator);
            }
            if(queue.length == 0){
                var operatorStr3 = expression;
                operatorStr3 = operatorStr3.replace(/\$\#leftbracket\$\#/g,"(").replace(/\$\#rightbracket\$\#/g,")");
                var operator = new op[opName]._class(operatorStr3,"expression_end");
                queue.push(operator);
            }
            
            var oprChain = getOperatorChain(queue);
            queue.forEach(function(opr){
                opr.setOperatorChain && opr.setOperatorChain(oprChain);
            });
            return queue;
        };
    
        var getOperatorChain = function(opQ){
            // var infos = [];
            var infos = self.operator.createArray();
            for(var i=0;i<opQ.length;i++){
                var op = opQ[i];
                var info = {
                    replacer:op.replacer,
                    expression:op.expression,
                    pre:null,
                    next:null,
                    tag:{} //用来在运算过程中存储临时数据
                }
                if(i > 0){
                    info.pre = infos[i-1];
                    if(i < opQ.length){
                        infos[i-1].next = info;
                    }
                }
                infos.push(info);
            }
            return infos;
        };
    
        var calculateQueue = function(opQueue){ 
            var resultCache = {};
            var operator = opQueue.shift();
            var cUnit = operator.calculate(resultCache);
            resultCache[cUnit.replacer] = cUnit.result;
            while(opQueue.length>0){
                operator = opQueue.shift();
                cUnit = operator.calculate(resultCache);
                resultCache[cUnit.replacer] = cUnit.result;
            }
            return cUnit;
        };
    
        // 同步计算
        var calculateSync = function(expression){
            try{
                var opQ = parse(expression);
                // console.log("生成表达式树",opQ);
                var cUnit = calculateQueue(opQ);
                if(cUnit.result === Infinity){
                    throw "计算错误";
                }
                return cUnit.result;
            }catch(e){
                return "";
            }
        };
    
        // 异步计算
        //根据公式生成结果
        var calculateAsync = function(expression,resultCall){
            if(expression === '') {
                return expression;
            };
            try{
                var opQueue = parse(expression);
                var resultCache = {};
                var operator = opQueue.shift();
                var cUnit = "";  
                var foo = function(){
                    if(self.operator.cacheExpressionVal.hasOwnProperty(expression) && self.operator.cacheExpressionVal[expression] != undefined) {
                        cb({
                            result:self.operator.cacheExpressionVal[expression],
                            replacer:operator.replacer
                        });
                    } else {
                        var unit = operator.calculate(resultCache);
                        if(self.operator.cacheExpressionVal.hasOwnProperty(expression) && self.operator.cacheExpressionVal[expression] == undefined && unit.replacer == 'expression_end') {
                            self.operator.cacheExpressionVal[expression] = unit.result;
                        }
                        cb(unit);
                    }
                };
                var cb = function(unit){
                    cUnit = unit;
                    resultCache[cUnit.replacer] = cUnit.result;
                    if(opQueue.length>0){
                        operator = opQueue.shift();
                        if(operator.isAsync) foo_async(); 
                        else foo();
                    }else{
                        if(cUnit.replacer == 'expression_end' && typeof cUnit.result == 'string'){
                            cUnit.result = cUnit.result.replace(/__ISNUMBER__|__ROUND__/g,'');
                        }
                        resultCall && resultCall(cUnit.result);
                    }
                };
                var foo_async = function(){
                    if(self.operator.cacheExpressionVal.hasOwnProperty(expression) && self.operator.cacheExpressionVal[expression] != undefined) {
                        cb_async({
                            result:self.operator.cacheExpressionVal[expression],
                            replacer:operator.replacer
                        });
                    } else {
                        operator.calculate(resultCache,function(unit){
                            if(self.operator.cacheExpressionVal.hasOwnProperty(expression) && self.operator.cacheExpressionVal[expression] == undefined && operator.replacer == "expression_end") {
                                self.operator.cacheExpressionVal[expression] = unit.result;
                            }
                            cb_async(unit);
                        });
                    }
                };
                var cb_async = function(unit){
                    cUnit = unit;                    
                    resultCache[cUnit.replacer] = cUnit.result;
                    if(opQueue.length>0){
                        operator = opQueue.shift();
                        if(operator.isAsync) foo_async(); 
                        else foo(); 
                    }else{
                        if(cUnit.replacer == 'expression_end' && typeof cUnit.result == 'string'){
                            cUnit.result = cUnit.result.replace(/__ISNUMBER__|__ROUND__/g,'');
                        }
                        resultCall && resultCall(cUnit.result);
                    }
                };
                if(operator.isAsync) foo_async(); 
                else foo();
                return expression;
            }catch(e){
                console.log(e)
                if(resultCall){
                    resultCall(false);
                }
            }
        };
        
        return{
            // 同步计算
            calculate:calculateSync,
            // 异步计算
            calculateAsync:calculateAsync
        }
    },
    rndNum:function(n){
        var rnd="";
        for(var i=0;i<n;i++)
            rnd+=Math.floor(Math.random()*10);
        return rnd;
    },
    isExpressionContainSubTable(ori_expression){
        var self = this;
        var tables = self.parser.involves(ori_expression);
        if(tables.length == 0) return false;
        if(tables.length>1) return true;
        if(tables.length===1){
            return tables[0] !== "main";
        }
    }
};
function isExpressionValid(ori_expression,tableCode){
    var tables = calculateExpression.parser.involves(ori_expression);
    if(tables.length == 0) return true;
    if(tableCode === "main"){
        if(tables.length == 1){
            if(tables.indexOf(tableCode)>-1) return true;
            return false;
        }else{
            return false;
        }
    }else{
        if(tables.length == 1){
            if(tables.indexOf(tableCode)>-1 || tables.indexOf("main")>-1) return true;
            return false;
        }
        if(tables.length == 2){
            if(tables.indexOf(tableCode)>-1 && tables.indexOf("main")>-1) return true;
            return false;
        }
        return false;
    }
}

calculateExpression.arithmetic = (function(){

    var operators = {
        "0":">",
        "1":"≥",
        "2":"<",
        "3":"≤",
        "4":"=",
        "5":"+",
        "6":"-",
        "7":"*",
        "8":"/",
        "9":"%",
        "10":"≠",
        "11":"⊇",
        "12":"⊉"
    };

    var handleOperators = {
        "1":"+",
        "2":"-",
        "3":"*",
        "4":"/",
        "5":"%"
    };
    
    //获取运算符
    var getOprs = function(){
        return common.getValues(operators);
    };
    var getHandleOprs = function(){
        return common.getValues(handleOperators);
    };

    var compareOprs = function(opr1,opr2){
        var lopr1 = -1;
        var lopr2 = -1;
        for(var lvl in operators){
            if(operators[lvl] === opr1) lopr1 = lvl;
            if(operators[lvl] === opr2) lopr2 = lvl;
        }
        lopr1 = lopr1*1;
        lopr2 = lopr2*1;
        if(lopr1 == lopr2) return 0;
        if(lopr1 > lopr2) return 1;
        if(lopr1 < lopr2) return -1;
    };

    var oprSplit = function(expression){
        if(typeof expression == 'string'){
            expression = expression.replace("==","=");
            if(expression.indexOf('__ISNUMBER__') != -1){
                expression = expression.replace(/__ISNUMBER__|__ROUND__/g,"");
            }
        }
        var chars = expression.split("");
        var ss = [];
        var temp = "";
        for(var i=0;i<chars.length;i++){
            var char = chars[i];
            if (char == '-' && /\W|,/g.test(chars[i - 1])) {
                temp = '-';
            } else if(isOperator(char)){
                if(temp !== ""){
                    if(temp === "''"){
                        ss.push("0");
                    } else {
                        ss.push(common.trim(temp));
                    }
                    temp = "";
                }
                ss.push(char);
            }else{
                temp = temp + char;
            }
        }
        if(temp !== ""){
            ss.push(common.trim(temp));
        }
        return ss;
    };

    //判断是否是算术表达式. ignoreNullValue:空值是否忽略(例如计算时可当作0处理)
    var isArithmetical = function(expression,ignoreNullValue){
        var chars = oprSplit(expression);
        if(chars.length == 0) return false;
        var oprs = getOprs();
        for(var i=0;i<chars.length;i++){
            var char = chars[i];
            if(char === '' || char === "''"){
                if(ignoreNullValue === true) continue;
            }
            if(common.isStrNumber(common.trim(char))===false && oprs.indexOf(char) === -1){
                return false;
            }
        }
        return true;
    };

    var isHandleArithmetical = function(expression,ignoreNullValue){
        var chars = oprSplit(expression);
        if(chars.length == 0) return false;
        var oprs = getHandleOprs();
        for(var i=0;i<chars.length;i++){
            var char = chars[i];
            if(char === '' || char === "''"){
                if(ignoreNullValue === true) continue;
            }
            if(common.isNumber(common.trim(char))===false && oprs.indexOf(char) === -1){
                return false;
            }
        }
        return true;
    };
    //是否是算术运算符
    var isOperator = function(char){
        var oprs = getOprs();
        return oprs.indexOf(char)>-1;
    };

    //替换正号为（#），替换负号（-）为@
    var replaceSigns = function(expression){
        var items = oprSplit(expression);
        for(var i=0;i<items.length;i++){
            var c = items[i];
            var pre = i == 0?"":items[i-1];
            var next = i+1<items.length?items[i+1]:"";
            if(isOperator(c) && isOperator(pre) && i+1<items.length && isOperator(next)){
                //连续三个或以上的运算符的错误写法：忽略。造成的运算错误：不管
                items.splice(i,1); i = -1; continue;
            }
            if(c === "+"){
                if(i == 0 || isOperator(pre)){
                    if(i+1<items.length){
                        items[i+1] = "#"+items[i+1];
                    }
                    items.splice(i,1); i = -1; continue;
                }
            }
            if(c === "-"){
                if(i == 0 || isOperator(pre)){
                    if(i+1<items.length){
                        items[i+1] = "@"+items[i+1];
                    }
                    items.splice(i,1); i = -1; continue;
                }
            }
        }
        return items;
    };

    //将原始表达式序列转换成逆波兰式的序列
    var convertToRPN = function(splitItems){
        var s1 = []; //运算符栈
        var s2 = []; //运算数栈
        var items = splitItems;

        for(var i=0;i<items.length;i++){
            var c = items[i];
            if(common.isStrNumber(c.replace("#","").replace("@",""))){
                s2.push(c); continue;
            }
            if(isOperator(c)){
                if(i == 0){
                    s1.push(c);continue;
                }else{
                    if(s1.length == 0){
                        s1.push(c);continue;
                    }else{
                        if(compareOprs(s1[s1.length-1],c)<0){
                            s1.push(c);
                        }else{
                            while(s1.length>0 && compareOprs(s1[s1.length-1],c)>=0){
                                s2.push(s1.pop());
                            }
                            s1.push(c);
                        }
                    }
                    continue;
                }
            }
        }
        while(s1.length>0){
            s2.push(s1.pop());
        }
        return s2;
    };

    //逆波兰式求值
    var runRPN = function(rpn){
        var rpnStr = rpn.join(" "); //用来记录原始rpn
        var foundHandler = function(si){
            return isOperator(si);
        };
        var oprIdx = common.findBackwardCst(rpn,foundHandler);
        if(oprIdx == -1){ return rpnStr};
        var value = "";
        while(oprIdx >-1){
            if(typeof rpn[oprIdx-2] === "undefined" || typeof rpn[oprIdx-1] === "undefined"){
                throw "错误的逆波兰式 "+ rpnStr;
            }
            var lft = rpn[oprIdx - 2];
            var rgt = rpn[oprIdx - 1];
            var opr = rpn[oprIdx];
            value = evaluation(lft,rgt,opr).toString();
            rpn[oprIdx - 2] = value; //把左值替换成计算结果
            rpn.splice(oprIdx - 1,2);//移除右值和运算符
            oprIdx = common.findBackwardCst(rpn,foundHandler);
        }
        
        return value;
    };

    var evaluation = function(lft,rgt,opr){
        lft = lft.replace("#","+").replace("@","-");
        rgt = rgt.replace("#","+").replace("@","-");
        if(opr === "+"){ 
            if(/^\'(.*?)\'$/.test(common.trim(rgt))){
                return lft + common.noQuot(rgt);
            } else {
              return  (new Number(lft)).add(new Number(rgt));
            }
        }
        if(opr === "-") return (new Number(lft)).sub(new Number(rgt));
        if(opr === "*") return (new Number(common.noQuot(lft))).mul(new Number(common.noQuot(rgt)));
        if(opr === "/") {
            var val = (new Number(common.noQuot(lft))).div(new Number(common.noQuot(rgt)));
            if(isFinite(val))return val;
            return 0;
        }
        if(opr === ">"){
            var expression = "gt("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["gt"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "≥"){
            var expression = "ge("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["ge"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "<"){
            var expression = "lt("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["lt"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "≤"){
            var expression = "le("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["le"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "="){
            var expression = "eq("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["eq"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "≠"){
            var expression = "ne("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["ne"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "⊇"){
            var expression = "like("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["like"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        if(opr === "⊉"){
            var expression = "notlike("+lft+","+rgt+")";
            var operator = new calculateExpression.operator["notlike"]._class((expression),"expression_end");
            var data = operator.calculate();
            return data.result;
        }
        return eval(lft + opr + rgt);
    };

    var calculate = function(expression){
        expression = expression.replace(/[\(\)]/g,'');
        if(isArithmetical(expression,true)===false) return expression;   
        //先替换一轮
        var items = replaceSigns(expression);
        var rnp = convertToRPN(items);
        var value = runRPN(rnp);
        return value;
    };
    // ie9不兼容repeat这个方法，重写
    var repeats = function (target, n) {
        var s = target, total = "";
        while (n > 0) {
            if (n % 2 == 1) {
                total += s;
            }
            if (n == 1) {
                break;
            }
    
            s += s;
            n = n >> 1;//相当于将n除以2取其商，或者说是开2次方
        }
        return total;
    };
    //精度计算
    var operationNumber = function (arg1,arg2,operator) {
        var oper=['+','-','*','/'];
        // 不合法的运算
        if (isNaN(arg1)||isNaN(arg2)||oper.indexOf(operator)<0) {
            return NaN;
        }
        // 除以0
        if (operator==='/'&&Number(arg2)===0) {
            return 0;
        }
        // 和0相乘
        if (operator==='*'&&Number(arg2)===0) {
            return 0;
        }
        // 相等两个数字相减
        if ((arg1===arg2||Number(arg1)===Number(arg2))&&operator==='-') {
            return 0;
        }
        var r1, r2, max,_r1,_r2;
        try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
        try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
        
        max = Math.max(r1, r2)
        _r1 = max-r1;
        _r2 = max-r2;
        if (_r1!==0) {
            arg1=arg1+ repeats('0',_r1)
        }
        if (_r2!==0) {
            arg2=arg2+repeats('0',_r2)
        }
        arg1 = Number(arg1.toString().replace('.',''))
        arg2 = Number(arg2.toString().replace('.',''))
        var r3 = operator==='*'?(max*2):(operator==='/'?0:max);
        var newNum = eval(arg1+operator+arg2);
        if (r3!==0) {
            var nStr = newNum.toString();
            nStr = nStr.replace(/^-/,'');
            if (nStr.length<r3+1) {
                nStr = repeats('0',r3+1-nStr.length)+nStr;
            }
            nStr = nStr.replace(new RegExp('(\\\d{'+r3+'})$'),'.$1');
            if (newNum<0) {
                nStr = '-'+nStr;
            }
            newNum = nStr*1;
        }
        
        if(isFinite(newNum))return newNum;
        return 0;
    };
    return{
        isArithmetical:isArithmetical,
        isHandleArithmetical:isHandleArithmetical,
        calculate:calculate,
        operationNumber:operationNumber,
        getOperators:function(){
            var oprs = [];
            for(var key in operators){
                oprs.push(operators[key]);
            }
            return oprs;
        },
        getHandleOperators:function(){
            var oprs = [];
            for(var key in handleOperators){
                oprs.push(handleOperators[key]);
            }
            return oprs;
        }
    }
})();

// 解决四则运算,js计算失去精度的问题 
//加法   
Number.prototype.add = function(arg){   
    var r1,r2,m;
    try{r1=this.toString().split(".")[1].length;}catch(e){r1=0;}
    try{r2=arg.toString().split(".")[1].length;}catch(e){r2=0;}
    m=Math.pow(10,Math.max(r1,r2));
    return (this.mul(m)+arg.mul(m)).div(m); 
};
//减法   
Number.prototype.sub = function (arg){   
    return this.add(-arg);
};
//乘法   
Number.prototype.mul = function (arg)   
{   
    var m=0,s1=this.toString(),s2=arg.toString();   
    try{m+=s1.split(".")[1].length;}catch(e){}   
    try{m+=s2.split(".")[1].length;}catch(e){}   
    return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);
};
//除法   
Number.prototype.div = function (arg){   
    var t1=0,t2=0,r1,r2;   
    try{t1=this.toString().split(".")[1].length;}catch(e){}   
    try{t2=arg.toString().split(".")[1].length;}catch(e){}   
    
    var r1 = Number(this.toString().replace(".",""));
    var r2 = Number(arg.toString().replace(".",""));
    return (r1/r2)*Math.pow(10,t2-t1);
};


/* operator- start */
var arithmetic = calculateExpression.arithmetic;
 var operator = {};
 operator.calculateUnit = function(lastResult,replacer){
     return {
         result:lastResult,
         replacer:replacer
     };
 };
 operator.matchResult = function(arr){
     return {
         value:arr,
         toString:function(){
            return arr.join("");
         }
     }
 };
 
 operator.functionConfigs = {};
 // 需要传入给apieval的参数
 operator.apievalObj = {};
 
 // 计算缓存数据
 operator.cacheExpressionVal = {};
 // 子表隐藏户安全
 operator.HiddeGourpCache = {};
 operator.createArray = function(){
     var arr = new Array();
     arr.setChainTag = function(replacer,key,value){
         var oprThis = null;
         this.forEach(function(opr){
             if(opr.replacer == replacer) oprThis = opr;
         });
         if(oprThis) oprThis.tag[key] = value;
     };
     arr.getOpr = function(replacer){
         var oprThis = null;
         this.forEach(function(opr){
             if(opr.replacer == replacer) oprThis = opr;
         });
         return oprThis;
     };
     return arr;
 };
 
 //*** 圆括号 */
 operator.parenthesis = (function(){
 
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var arr = stack.slice(i);        
         return new operator.matchResult(arr);
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         var oprChain = operator.createArray();
         var getPreTag = function(){
             var oprThis = null;
             oprChain.forEach(function(opr){
                 if(opr.expression == s_expression) oprThis = opr;
             });
             var preOpr = oprThis?oprThis.pre:null;
             if(preOpr) return preOpr.tag;
             return null;
         };
 
         var getPreReturnType =function(){
             var preType = "";
             var tag = getPreTag();
             if(tag && tag["return_type"]) preType = tag["return_type"];
             return preType;
         };
         
         var getRetrunRoundFlags = function(){
             var exps = [];
             oprChain.forEach(function(opr){
                  if(opr.tag && opr.tag["return_type"] && opr.tag["return_type"].indexOf("round-") === 0){
                      exps.push(opr.replacer);
                  }
             });
             return exps;
         };
 
         var getOprByExp = function(exp){
             var foundOpr = null;
             oprChain.forEach(function(opr){
                 if(opr.replacer == exp) foundOpr = opr;
             });
             return foundOpr;
         };
 
         var getRetrunStringFlags = function(){
             var exps = [];
             oprChain.forEach(function(opr){
                  if(opr.tag && opr.tag["return_type"] && opr.tag["return_type"] === "string"){
                      exps.push(opr.replacer);
                  }
             });
             return exps;
         };
 
         var checkHasFlag = function(flags,expression){
             // var expression = oprChain.getOpr(replacer).expression;
             for(var i = 0;i<flags.length;i++){
                 if(expression.indexOf(flags[i]) !== -1)
                     return true;
             } 
             return false;            
         };
 
         var trimExpressionSpace = function(flags,expression){
             for(var i = 0;i<flags.length;i++){
                 var flag = flags[i];
                 if(expression.indexOf(flag) !== -1){
                     while(expression.indexOf(flag+" ")>-1){
                         expression = expression.replace(flag+" ",flag);
                     }
                     while(expression.indexOf(" "+flag)>-1){
                         expression = expression.replace(" "+flag,flag);
                     }
                 }
             }
             return expression;
         };
 
         var replaceStringFlag = function(flags,expression,arithmeticOprs,oprReplacer){
             for(var i = 0;i<flags.length;i++){
                 var flag = flags[i];
                 if(expression.indexOf(flag) !== -1){
                     arithmeticOprs.forEach(function(opchar){
                         while(expression.indexOf(flag+opchar)>-1){
                             expression = expression.replace(flag+opchar,flag+oprReplacer);
                         }
                         while(expression.indexOf(opchar+flag)>-1){
                             expression = expression.replace(opchar+flag,oprReplacer+flag);
                         }
                     });
                 }
             }
             return expression;
         };
 
         var parseLikeNoLike = function(calculate_expression){
             if(calculate_expression.indexOf('⊇') != -1 || calculate_expression.indexOf('⊉') != -1){
                 calculate_expression = calculate_expression.replace(/([^⊇⊉&|\(\)]+)([⊇⊉])([^⊇⊉&|\(\)]+)/ig,function(a,b,c,d){
                     b = eval(b.replace(/__ISNUMBER__|__ROUND__/g,'').replace(/≥/g,">=").replace(/≤/g,"<=").replace(/≠/g,"!="));
                     d = eval(d.replace(/__ISNUMBER__|__ROUND__/g,'').replace(/≥/g,">=").replace(/≤/g,"<=").replace(/≠/g,"!="));
                     return (c == '⊇') ? (((b||'')+'').indexOf(d) != -1) : (((b||'')+'').indexOf(d) == -1);
                 });
             }
             return calculate_expression;
         }
 
         var calculatePriority = function(subExpression){
             var arr1 = subExpression.split("+");
             var items = [];
             arr1.forEach(function(item1){
                 var arr2 = item1.replace(/((^|[^\d\)])-((0|([1-9]\d*))(\.\d+)?|\d+))/g,"$1@").match(/\(|\)|\+|-(((0|([1-9]\d*))(\.\d+)?|\d+)(?=@))?|\*|\/|((0|([1-9]\d*))(\.\d+)?|\d+)/g);
                 var str = "";
                 arr2.forEach(function(item2,index){
                     if(item2 == "-"){
                         items.push(str);
                     } else if(index==arr2.length-1){
                         str+=item2;
                         items.push(str);
                     } else {
                         str+=item2;
                     }
                 });
             });
 
             for(var i=0;i<items.length;i++){
                 var itemExpression = items[i];
                 if(!common.isNumber(itemExpression)){
                     items[i] = arithmetic.calculate(itemExpression);
                 }
             }
             return items.join("");
         };
         
 
         var calculate = function(resultCache){
             var calculate_expression = s_expression;
             if(calculate_expression.indexOf("(")>-1 && calculate_expression.lastIndexOf(")")===calculate_expression.length-1){
                 calculate_expression = common.noParenthesis(calculate_expression);
             }
             var result = "";
             var preType = getPreReturnType();
             var oprParams = [];
             var isBlooan = false;
             var stringFlags = getRetrunStringFlags();
             var hasStringFlag = checkHasFlag(stringFlags,calculate_expression);
             if(hasStringFlag){
                 calculate_expression = trimExpressionSpace(stringFlags,calculate_expression);
                 calculate_expression = replaceStringFlag(stringFlags,calculate_expression,arithmetic.getHandleOperators(),"[str-add]");
                 oprParams = calculate_expression.split("[str-add]");
                 for(var i=0;i<oprParams.length;i++){
                     var subExpression = oprParams[i];
                     if(stringFlags.indexOf(subExpression) === -1){
                         subExpression = common.fullReplace(subExpression,resultCache,true);  
                         if(arithmetic.isHandleArithmetical(subExpression,false)){ // 需求设定取消，true改为false，影响点最小化
                             //【需求设定】空值作为0处理
                             subExpression = common.allReplace(subExpression,"''","0");
                             subExpression = common.allReplace(subExpression,common.unknownValue(),"0");
                             oprParams[i] = arithmetic.calculate(subExpression)*1;
                         }else{
                             if(arithmetic.isArithmetical(subExpression,false)){
                                 subExpression = common.allReplace(subExpression,"''","0");
                                 subExpression = common.allReplace(subExpression,common.unknownValue(),"0");
                                 oprParams[i] = arithmetic.calculate(subExpression);
                             }else {
                                 if(typeof subExpression == 'string'){
                                     //IF函数第一个参数需要严格区分数值和字符串数值，所以给数值加个标识
                                     if(subExpression.indexOf('__ISNUMBER__') != -1){
                                         subExpression = subExpression.replace(/NaN/g,'').replace(/['"]__ISNUMBER__(?:__ROUND__)?(-?\d+(\.\d+)?)+['"]/g,function(r1,r2){
                                             return r2;
                                         });
                                     }
                                 }
                                 subExpression = parseLikeNoLike(subExpression);
                                 oprParams[i] = eval(String(subExpression).replace(/≥/g,">=").replace(/≤/g,"<=").replace(/≠/g,"!="))+"";
                             }
                         }
                     }else{
                         oprParams[i] = common.fullReplace(subExpression,resultCache);
                     }
                 }
             }else{
                 calculate_expression =  common.fullReplace(s_expression,resultCache);
             }  
             if(typeof calculate_expression == 'string'){
                 if(calculate_expression.indexOf('__ISNUMBER__') != -1){
                     calculate_expression = calculate_expression.replace(/__ISNUMBER__|__ROUND__/g,'');
                 }
             }
             try{
                 if(hasStringFlag === true){
                     oprParams.forEach(function(item){
                         if(typeof item == 'string'){
                             if(item.indexOf('__ISNUMBER__') != -1){
                                 item = item.replace(/__ISNUMBER__|__ROUND__/g,'').replace(/NaN/g,'');
                             }
                             item = item.replace(/^'|"/,'').replace(/'|"$/,'');
                         }
                         result = result.toString() + item.toString();
                     });
                     result = result.toString();
                     if(result === "true"){
                         result = true;
                     } else if(result === "false"){
                         result = false;
                     }
                     oprChain.setChainTag(s_replacer,"return_type","string");
                 }else{
                     if(preType === "number" || preType === "" || preType.indexOf("round-") === 0){
                         // if(arithmetic.isArithmetical(calculate_expression,true)){
                         var roundFlags = getRetrunRoundFlags();
                         var round_count_0 = 0;
                         if(checkHasFlag(roundFlags,s_expression)){
                             var temp_exp = trimExpressionSpace(roundFlags,s_expression);
                             temp_exp = replaceStringFlag(roundFlags,temp_exp,arithmetic.getOperators(),"[temp]");
                             var numberExpArr = temp_exp.split("[temp]");
                             numberExpArr.forEach(function(numExp){
                                 if(roundFlags.indexOf(numExp)>-1){
                                     var opr = getOprByExp(numExp);
                                     if(opr.tag && opr.tag["return_type"] && opr.tag["return_type"].indexOf("round-") === 0){
                                         var strArr = opr.tag["return_type"].split("-");
                                         var c_0 = (strArr.length <2 ?0:strArr[1])*1;
                                         if(round_count_0<c_0) round_count_0 = c_0;
                                     }
                                 }
                             });
                         }
                         if(arithmetic.isArithmetical(calculate_expression,false)){ // 需求设定取消，true改为false，影响点最小化
                             //【需求设定】空值作为0处理
                             calculate_expression = common.allReplace(calculate_expression,"''","0");
                             calculate_expression = common.allReplace(calculate_expression,common.unknownValue(),"0");
                             if(common.isNumber(calculate_expression)){
                                 result = calculate_expression*1;
                             } else {
                                 result = arithmetic.calculate(calculate_expression);
                                 if(result !== "true" && result !== "false"){
                                     result = result*1;
                                 } else {
                                     if(result === "true"){
                                         result = true;
                                         isBlooan = true;
                                     } else if(result === "false"){
                                         result = false;
                                         isBlooan = true;
                                     }
                                 }                        
                             }
                             if(round_count_0 > 0 && !isBlooan){
                                 result = common.buZero(result,round_count_0);
                                 oprChain.setChainTag(s_replacer,"return_type","round-"+round_count_0);
                             }   
                         }else{
                             //数值与文本混合计算时，应该先计算文本前面的四则运算表达式，否则用eval计算小数会丢失精度
                             //如"1+0.1+0.2+'文本'+100+200"，应该先算1+0.1+0.2，后面再和字符串拼接，否则0.1+0.2就会丢失精度
                             if(calculate_expression.indexOf("'") ==0 || calculate_expression.indexOf('"') == 0 ){//如果计算结果为字符串开头，则不做处理
                             }else{
                                 var getArithmetical = String(calculate_expression).split(/.'|."/g);
                                 if(getArithmetical && getArithmetical.length){
                                     calculate_expression = calculate_expression.replace(getArithmetical[0],arithmetic.calculate(getArithmetical[0]));
                                 }
                             }
 
                             calculate_expression = parseLikeNoLike(calculate_expression);
                             
                             result = eval(String(calculate_expression).replace(/≥/g,">=").replace(/≤/g,"<=").replace(/≠/g,"!=").replace(/\n/g,"<br>"));
                             if(result !== true && result !== false){
                                 result = result.toString();
                             }
                         }
                     }else{
                         calculate_expression = parseLikeNoLike(calculate_expression);
                         result = eval(String(calculate_expression).replace(/≥/g,">=").replace(/≤/g,"<=").replace(/≠/g,"!="));
                         if(result !== true && result !== false){
                             result = result.toString();
                         }
                     }
                 }
             }catch(e){
                 result = "";
             }
             if(result === "undefined") result = "";
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer,
             setOperatorChain:function(opc){oprChain = opc;}
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.PARENTHESIS = operator.parenthesis;
 
 //*** 求和 */
 operator.sum = (function(){
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         if(i-3<0) return null;
         if(stack.slice(i-3,i).join("").toLowerCase() == "sum"){
             var arr = stack.slice(i-3);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
     
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         // 找出小数位数
         // var selectNum = function(val){
         //     var arr = val.split('.')
         //     var numlength = 0 // 记录小数位数
         //     for(var i=0;i<arr.length;i++){
         //         var num = arr[i].replace(new RegExp("\\/.*|\\*.*|\\+.*|\\-.*|\\(.*|\\).*","g"),"").length
         //         if(num>numlength){
         //             numlength = num
         //         }
         //     }
         //     return numlength
         // }
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) {return new operator.calculateUnit(false,s_replacer);};
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("sum\\(","ig"),"").replace(")","").getParams();
             // 异常处理
             try {
                 var sum = 0;
                 for(var i = 0;i<params.length;i++){
                     var p = params[i];
                     if(typeof p == 'string' && p.indexOf('__ISNUMBER__') != -1){
                         p = Number(p.replace(/__ISNUMBER__|__ROUND__/g,'')) || 0;
                     }
                     if(p!="''" && p!=null && p!="" && p!="undefined"){
                         if(common.isNumber(p)){
                             sum = arithmetic.operationNumber(sum,p,'+')
                         } else {
                             // sum = sum + arithmetic.calculate(p) *1 此方法处理不了带空字符的表达式
                             sum = arithmetic.operationNumber(sum, eval(p),'+')
                         }
                     }
                 }
                 if(common.isNumber(sum) || common.isScience(sum)){// 判断是否为数字&科学计数法
                     sum = '__ISNUMBER__' + sum;
                     return new operator.calculateUnit(sum,s_replacer);
                 } else {
                     return new operator.calculateUnit(0,s_replacer);
                 }
                 
             } catch (error) {
                 return new operator.calculateUnit(0,s_replacer);
             }
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 //符号大小写兼容
 operator.SUM = operator.sum;
 
 //*** 等于 (用于字符串和数字) */
 operator.eq = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "eq"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("eq\\(","ig"),"").replace(")","").getParams();
             var result = false;
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if(common.isStrNumber(lftVal) && common.isStrNumber(rgtVal)){
                     if(lftVal*1.0 === rgtVal*1.0) result = true;
                 }else{
                     if(lftVal.toString() === rgtVal.toString()) result = true;
                 }
             }
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.EQ = operator.eq;
 
 //*** 不等于 (用于字符串和数字) */
 operator.ne = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ne"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // 返回_unknown_value_，不做处理
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(true,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ne\\(","ig"),"").replace(")","").getParams();
             var result = false;
             if(params.length == 2){
                 // debugger;
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if(common.isNumber(lftVal) && common.isNumber(rgtVal)){
                     if(lftVal*1.0 !== rgtVal*1.0) result = true;
                 }else{
                     if(lftVal.toString() !== rgtVal.toString()) result = true;
                 }
             }
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NE = operator.ne;
 
 //*** 相似 (字符串) */
 operator.like = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-4;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "like"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression = common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("like\\(","ig"),"").replace(")","").replace(/[\r\n]/g, "").getParams();
             var result = false;
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 var lftValArr = lftVal.split(",");
                 var rgtValArr = rgtVal.split(",");
                 if(lftValArr.length > 1){
                     if(rgtValArr.length == 0){
                         for(var i=0;i<lftValArr.length;i++){
                             var lv = lftValArr[i];
                             var rv = rgtVal;
                             if(lv === rv){
                                 result = true;
                             }
                         }
                     }else{
                         result = lftVal.indexOf(rgtVal) > -1;
                     }
                 }else{
                     result = lftVal.indexOf(rgtVal) > -1;
                 }
             }
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.LIKE = operator.like;
 
 //*** 不包含 (字符串) */
 operator.notlike = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-8;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "not-like"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // 返回_unknown_value_，不做处理
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression = common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("not-like\\(","ig"),"").replace(")","").replace(/[\r\n]/g, "").getParams();
             var result = true;
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 var lftValArr = lftVal.split(",");
                 var rgtValArr = rgtVal.split(",");
                 if(lftValArr.length > 1){
                     if(rgtValArr.length == 0){
                         for(var i=0;i<lftValArr.length;i++){
                             var lv = lftValArr[i];
                             var rv = rgtVal;
                             if(lv === rv){
                                 result = false;
                             }
                         }
                     }else{
                         result = lftVal.indexOf(rgtVal) === -1;
                     }
                 }else{
                     result = lftVal.indexOf(rgtVal) === -1;
                 }    
             }else{
                 //参数不合法直接返回false
                 result = false;
             }
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NOTLIKE = operator.notlike;
 
 //*** 以开头 (字符串) */
 operator.beginwith = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "beginwith"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("beginwith\\(","ig"),"").replace(")","").replace(/[\r\n]/g, "").getParams();
             var result = false;
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if(lftVal.indexOf(rgtVal)===0)
                     result = true;
             }
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.BEGINWITH = operator.beginwith;
 
 //*** 为空 */
 operator.isnull = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-4;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "null"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("null\\(","ig"),"").replace(")","").getParams();
             var result = false;
             var val = common.noQuot(params[0]);
             if(typeof val === "undefined" || val === null || val.toString() === "" || val.toString() ===''){
                 result = true;
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.ISNULL = operator.isnull;
 
 //*** 不为空 */
 operator.notnull = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-8;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "not-null"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("not-null\\(","ig"),"").replace(")","").getParams();
             var result = false;
             var val = common.noQuot(params[0]);
             if(typeof val !== "undefined" && val !== null && val.toString() !== "" && val.toString() !=='' && val.toString() !=='[]'){
                 result = true;
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NOTNULL = operator.notnull;
 
 //*** 大于 */
 operator.gt = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "gt"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // 当返回_unknown_value_时，转成0 参与计算
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             // if(s_expression.indexOf(common.unknownValue())>-1){
             //     s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             // }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("gt\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if(common.isNumber(lftVal) && common.isNumber(rgtVal)){
                     if(lftVal*1 > rgtVal*1){
                         result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.GT = operator.gt;
 
 //*** 大于等于 */
 operator.ge = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ge"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // 当返回_unknown_value_时，转成0 参与计算
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ge\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if(common.isNumber(lftVal) && common.isNumber(rgtVal)){
                     if(lftVal*1 >= rgtVal*1){
                         result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.GE = operator.ge;
 
 //*** 小于 */
 operator.lt = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "lt"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // 当返回_unknown_value_时，转成0 参与计算
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             // if(s_expression.indexOf(common.unknownValue())>-1){
             //     s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             // }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("lt\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if(common.isNumber(lftVal) && common.isNumber(rgtVal)){
                     if(lftVal*1 < rgtVal*1){
                         result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.LT = operator.lt;
 
 //*** 小于等于 */
 operator.le = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "le"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // 当返回_unknown_value_时，转成0 参与计算
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("le\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 lftVal = lftVal == "" ? 0:lftVal;
                 if(common.isNumber(lftVal) && common.isNumber(rgtVal)){
                     if(lftVal*1 <= rgtVal*1){
                         result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.LE = operator.le;
 
 //*** 等于(日期，精确到天) */
 operator.eqdate = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "eq-date-d"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("eq-date-d\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if (!lftVal && !rgtVal) {
                     result = true;
                 } else {
                     var lftDate = new Date(lftVal.replaceAll("-","/"));
                     var rgtDate = new Date(rgtVal.replaceAll("-","/"));
                     if(lftDate.getFullYear() === NaN || rgtDate.getFullYear() === NaN){
                         throw "日期格式不合法";
                     }
                     if(lftDate.getFullYear() === rgtDate.getFullYear()
                         && lftDate.getMonth() === rgtDate.getMonth()
                         && lftDate.getDate() === rgtDate.getDate()){
                              result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.EQDATE = operator.eqdate;
 
 //*** 不等于(日期，精确到天) */
 operator.nedate = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ne-date-d"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ne-date-d\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if (!lftVal && !rgtVal) {
                     result = false;
                 }else{
                     var lftDate = new Date(lftVal.replaceAll("-","/"));
                     var rgtDate = new Date(rgtVal.replaceAll("-","/"));
                     if(lftDate.getFullYear() === NaN || rgtDate.getFullYear() === NaN){
                         throw "日期格式不合法";
                     }
                     if(lftDate.getFullYear() !== rgtDate.getFullYear()
                         || lftDate.getMonth() !== rgtDate.getMonth()
                         || lftDate.getDate() !== rgtDate.getDate()){
                              result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NEDATE = operator.nedate;
 
 //*** 大于(日期，精确到天) */
 operator.gtdate = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "gt-date-d"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("gt-date-d\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 var lftDate = new Date(lftVal.replaceAll("-","/"));
                 var rgtDate = new Date(rgtVal.replaceAll("-","/"));
                 if(lftDate.getFullYear() === NaN || rgtDate.getFullYear() === NaN){
                     throw "日期格式不合法";
                 }
                 if(lftDate.getFullYear() > rgtDate.getFullYear()
                 || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() > rgtDate.getMonth())
                 || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() === rgtDate.getMonth() && lftDate.getDate() > rgtDate.getDate())){
                      result = true;
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.GTDATE = operator.gtdate;
 
 //*** 大于等于(日期，精确到天) */
 operator.gedate = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ge-date-d"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             // if(s_expression.indexOf(common.unknownValue())>-1){
             //     s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             // }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ge-date-d\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if (!rgtVal) {
                     result = true;
                 } else {
                     var lftDate = new Date(lftVal.replaceAll("-","/"));
                     var rgtDate = new Date(rgtVal.replaceAll("-","/"));
                     if(lftDate.getFullYear() === NaN || rgtDate.getFullYear() === NaN){
                         throw "日期格式不合法";
                     }
                     if(lftDate.getFullYear() === rgtDate.getFullYear()
                         && lftDate.getMonth() === rgtDate.getMonth()
                         && lftDate.getDate() === rgtDate.getDate()){
                              result = true;
                     }
                     if(lftDate.getFullYear() > rgtDate.getFullYear()
                     || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() > rgtDate.getMonth())
                     || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() === rgtDate.getMonth() && lftDate.getDate() > rgtDate.getDate())){
                          result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.GEDATE = operator.gedate;
 
 //*** 小于(日期，精确到天) */
 operator.ltdate = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "lt-date-d"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("lt-date-d\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 var lftDate = new Date(lftVal.replaceAll("-","/"));
                 var rgtDate = new Date(rgtVal.replaceAll("-","/"));
                 if(lftDate.getFullYear() === NaN || rgtDate.getFullYear() === NaN){
                     throw "日期格式不合法";
                 }
                 if(lftDate.getFullYear() < rgtDate.getFullYear()
                     || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() < rgtDate.getMonth())
                     || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() === rgtDate.getMonth() && lftDate.getDate() < rgtDate.getDate())){
                          result = true;
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.LTDATE = operator.ltdate;
 
 //*** 小于等于(日期，精确到天) */
 operator.ledate = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-9;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "le-date-d"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             // if(s_expression.indexOf(common.unknownValue())>-1){
             //     s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             // }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("le-date-d\\(","ig"),"").replace(")","").getParams();
             var result = false;            
             if(params.length == 2){
                 var lftVal = common.noQuot(params[0]);
                 var rgtVal = common.noQuot(params[1]);
                 if (!rgtVal) {
                     result = true;
                 } else {
                     var lftDate = new Date(lftVal.replaceAll("-","/"));
                     var rgtDate = new Date(rgtVal.replaceAll("-","/"));
                     if(lftDate.getFullYear() === NaN || rgtDate.getFullYear() === NaN){
                         throw "日期格式不合法";
                     }
                     if(lftDate.getFullYear() === rgtDate.getFullYear()
                         && lftDate.getMonth() === rgtDate.getMonth()
                         && lftDate.getDate() === rgtDate.getDate()){
                              result = true;
                     }
                     if(lftDate.getFullYear() < rgtDate.getFullYear()
                     || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() < rgtDate.getMonth())
                     || (lftDate.getFullYear() === rgtDate.getFullYear() && lftDate.getMonth() === rgtDate.getMonth() && lftDate.getDate() < rgtDate.getDate())){
                          result = true;
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.LEDATE = operator.ledate;
 
 
 //*** 相等（人员） */
 operator.eqperson = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-16;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "eq-select-person"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","''");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("eq-select-person\\(","ig"),"").replace(")","").getJsonArrParams();
             var result = false;
             if(params && params.length == 2) {
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if ((!lftValArr || lftValArr.length == 0) && (!rgtValArr || rgtValArr.length == 0)) {
                     result = true;
                 } else if (lftValArr.length != rgtValArr.length) {
                     result = false;
                 } else {
                     var leftCodes = [];
                     lftValArr.forEach(function(item){
                         delete item.station_guid;
                         delete item.station_name;
                         if(item.auditor_code) leftCodes.push(item.auditor_code.toLowerCase());
                     });
                     result = true;
                     for (var i = 0; i < rgtValArr.length; i++) {
                         var code = rgtValArr[i].auditor_code.toLowerCase();
                         var index = leftCodes.indexOf(code);
                         if (index < 0) {
                             result = false;
                             break;
                         }
                         leftCodes.splice(index, 1);
                     }
                     result = result && leftCodes.length == 0;
                 }
             }
 
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.EQPERSON = operator.eqperson;
 
 //*** 不相等（人员） */
 operator.neperson = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-16;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ne-select-person"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","''");
             }
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ne-select-person\\(","ig"),"").replace(")","").getJsonArrParams();
             var result = false;
             if (params && params.length == 2) {
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 lftValArr.forEach(function(item){
                     delete item.station_guid;
                     delete item.station_name;
                 });
                 if ((!lftValArr || lftValArr.length == 0) && (!rgtValArr || rgtValArr.length == 0)) {
                     result = false;
                 } else if (lftValArr.length == 0 || lftValArr.length != rgtValArr.length) {
                     result = true;
                 } else {
                     var leftCodes = [];
                     lftValArr.forEach(function(item){
                         if(item.auditor_code) leftCodes.push(item.auditor_code.toLowerCase());
                     });
                     result = false;
                     for (var i = 0; i < rgtValArr.length; i++) {
                         var code = rgtValArr[i].auditor_code.toLowerCase();
                         var index = leftCodes.indexOf(code);
                         if (index < 0) {
                             result = true;
                             break;
                         }
                         leftCodes.splice(index, 1);
                     }
                     result = result || leftCodes.length > 0;
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NEPERSON = operator.neperson;
 
 /*** API函数 */
 operator.apieval = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-7;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "apieval"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         var oprChain = operator.createArray();
         
         var doValidate = function(dtype,data){
             if(dtype == "date"){
                var ok = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(\s([01][0-9]|[2][0-3]):[0-5][0-9])?(:[0-5][0-9])?$/.test(data);
                if(!ok) return "";
             }
             if(dtype == "number"){
                 if(parseFloat(data).toString() === "NaN" || typeof data !== "number") return 0;
             }
             return data;
         };
 
         var calculate = function(resultCache,resultCall){
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var argsString = common.noParenthesis(calculate_expression);
             var arr = argsString.split(",");

             var configs = operator.functionConfigs["apieval"];
             if(typeof configs === "undefined"){
                 oprChain.setChainTag(s_replacer,"return_type","string");
                 resultCall && resultCall(new operator.calculateUnit("",s_replacer));
                 return;
             }
             var params = [];
             arr.forEach(function(arg){
                 arg = common.noQuot(arg);
                 params.push(unescape(arg));
             });
             if(arr.length === 0) {
                 oprChain.setChainTag(s_replacer,"return_type","string");
                 resultCall && resultCall(new operator.calculateUnit("",s_replacer));
                 return;
             }
             var url = "",returnType = "";
             var businessType = params[0];//第一个参数是调用的业务类型
             var cfg = configs[businessType];
             if(typeof cfg === "undefined"){
                 oprChain.setChainTag(s_replacer,"return_type","string");
                 resultCall && resultCall(new operator.calculateUnit("",s_replacer));
                 return;
             }
             url = cfg.url;
             returnType =cfg.return_type.toLowerCase();
             var apievalData = ''
             
             if(calculate_expression.indexOf('onlyForPlanSystem')>-1){ 
                 var expdata = []
                 expdata = operator.apievalObj.expression.splice(0,params.length-1)
                 expdata.unshift("onlyForPlanSystem")
                 apievalData = {}
                 apievalData.expression = expdata;
                 var form_data = window?.tplData?.form?.form_data || {};
                 apievalData.form_data = {
                     main: form_data.main || {},
                     children: form_data.children || {}
                 }
             } else {
                 apievalData = []
                 apievalData = params
             }
             oprChain.setChainTag(s_replacer,"return_type",returnType);
             request({
                url: url,
                method: "POST",
                data:apievalData
              }).then(function (result) {
                    var rtnData = "";
                    if (result.code == 1) {
                      rtnData = result.data;
                      try {
                        switch (returnType) {
                          case "string":
                            rtnData = doValidate(returnType, rtnData + "");
                            break;
                          case "number":
                            rtnData = doValidate(returnType, rtnData * 1);
                            break;
                          case "date":
                            rtnData = doValidate(returnType, rtnData + "");
                            break;
                        }
                      } catch (e) {
                        switch (returnType) {
                          case "string":
                            rtnData = "";
                            break;
                          case "number":
                            rtnData = 0;
                            break;
                          case "date":
                            rtnData = "";
                            break;
                        }
                      }
                    } else {
                      rtnData = "";
                    }
                    resultCall && resultCall(new operator.calculateUnit(rtnData, s_replacer));
           
              },function(e){
                resultCall && resultCall(new operator.calculateUnit("",s_replacer));
              });
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer,
             isAsync:true,
             setOperatorChain:function(opc){oprChain = opc;}
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.APIEVAL = operator.apieval;
 
 //*** 相等（组织） */
 operator.eqorg = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-13;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "eq-select-org"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","''");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("eq-select-org\\(","ig"),"").replace(")","").getJsonArrParams();
             var result = false;
             if(params && params.length == 2) {
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if(!lftValArr && !rgtValArr) result = true;
                 else{
                     if(lftValArr && rgtValArr){
                         if(lftValArr.length == rgtValArr.length){
                             if(lftValArr.length == 0) result = true;
                             else{
                                 var leftCodes = [],rightCodes = [];
                                 lftValArr.forEach(function(item){
                                     if(item.org_id) leftCodes.push(item.org_id.toLowerCase());
                                 });
                                 rgtValArr.forEach(function(item){
                                     if(item.org_id) rightCodes.push(item.org_id.toLowerCase());
                                 });
                                 var leftNotInRight = leftCodes.length,rightNotInleft = rightCodes.length;
                                 leftCodes.forEach(function(code){
                                     if(rightCodes.indexOf(code) != -1) leftNotInRight --;
                                 });
                                 rightCodes.forEach(function(code){
                                     if(leftCodes.indexOf(code) != -1) rightNotInleft --;
                                 });
                                 if(leftNotInRight == 0 && rightNotInleft == 0){
                                     result = true;
                                 }
                             }
                         }
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.EQORG = operator.eqorg;
 
 //*** 不相等（组织） */
 operator.neorg = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-13;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ne-select-org"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ne-select-org\\(","ig"),"").replace(")","").getJsonArrParams();
             var isEq = false;
             if(params && params.length == 2) {
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if(!lftValArr && !rgtValArr) isEq = true;
                 else{
                     if(lftValArr && rgtValArr){
                         if(lftValArr.length == rgtValArr.length){
                             if(lftValArr.length == 0) isEq = true;
                             else{
                                 var leftCodes = [],rightCodes = [];
                                 lftValArr.forEach(function(item){
                                     if(item.org_id) leftCodes.push(item.org_id.toLowerCase());
                                 });
                                 rgtValArr.forEach(function(item){
                                     if(item.org_id) rightCodes.push(item.org_id.toLowerCase());
                                 });
                                 var leftNotInRight = leftCodes.length,rightNotInleft = rightCodes.length;
                                 leftCodes.forEach(function(code){
                                     if(rightCodes.indexOf(code) != -1) leftNotInRight --;
                                 });
                                 rightCodes.forEach(function(code){
                                     if(leftCodes.indexOf(code) != -1) rightNotInleft --;
                                 });
                                 if(leftNotInRight == 0 && rightNotInleft == 0){
                                     isEq = true;
                                 }
                             }
                         }
                     }
                 }
             }
             var result = !isEq;
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NEORG = operator.neorg;
 
 //*** 包含（组织） */
 operator.likeorg = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-15;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "like-select-org"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("like-select-org\\(","ig"),"").replace(")","").getJsonArrParams();
             var result = false;
             if (!params) {
                 result = true;
             }
             if (params && params.length == 2){
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if (!rgtValArr || rgtValArr.length == 0) {
                     result = true;
                 } else {
                     if (!lftValArr || lftValArr.length == 0) {
                         result = false;
                     } else {
                         result = true;
                         var leftCodes = [];
                         lftValArr.forEach(function(item){
                             if(item.org_id) leftCodes.push(item.org_id.toLowerCase());
                         });
                         for (var i = 0; i < rgtValArr.length; i++) {
                             var code = rgtValArr[i].org_id.toLowerCase();
                             if (leftCodes.indexOf(code) < 0) {
                                 result = false;
                                 break;
                             }
                         }
                     }
                 }
             }
 
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.LIKEORG = operator.likeorg;
 
 //*** 不包含（组织） */
 operator.notlikeorg = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-19;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "not-like-select-org"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("not-like-select-org\\(","ig"),"").replace(")","").getJsonArrParams();
             var result = false;
             if(params && params.length == 2){
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if ((!lftValArr || lftValArr.length == 0) && (!rgtValArr || rgtValArr.length == 0)) {
                     result = false;
                 } else {
                     if (!lftValArr || lftValArr.length == 0) {
                         result = true;
                     } else {
                         result = false;
                         var leftCodes = [];
                         lftValArr.forEach(function(item){
                             if(item.org_id) leftCodes.push(item.org_id.toLowerCase());
                         });
                         for (var i = 0; i < rgtValArr.length; i++) {
                             var code = rgtValArr[i].org_id.toLowerCase();
                             if (leftCodes.indexOf(code) < 0) {
                                 result = true;
                                 break;
                             }
                         }
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NOTLIKEORG = operator.notlikeorg;
 
 //*** 相等（城市选择） */
 operator.eqcity = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-14;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "eq-select-city"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","''");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("eq-select-city\\(","ig"),"").replace(")","").getJsonArrParams();
             var result = false;
             if(params && params.length == 2) {
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if(!lftValArr && !rgtValArr) result = true;
                 else{
                     if(lftValArr && rgtValArr){
                         if(lftValArr.length == rgtValArr.length){
                             if(lftValArr.length == 0) result = true;
                             else{
                                 var leftCodes = [],rightCodes = [];
                                 lftValArr.forEach(function(item){
                                     if(item.CityEN) leftCodes.push(item.CityEN.toLowerCase());
                                 });
                                 rgtValArr.forEach(function(item){
                                     if(item.CityEN) rightCodes.push(item.CityEN.toLowerCase());
                                 });
                                 var leftNotInRight = leftCodes.length,rightNotInleft = rightCodes.length;
                                 leftCodes.forEach(function(code){
                                     if(rightCodes.indexOf(code) != -1) leftNotInRight --;
                                 });
                                 rightCodes.forEach(function(code){
                                     if(leftCodes.indexOf(code) != -1) rightNotInleft --;
                                 });
                                 if(leftNotInRight == 0 && rightNotInleft == 0){
                                     result = true;
                                 }
                             }
                         }
                     }
                 }
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.EQCITY = operator.eqcity;
 
 //*** 不相等（城市选择） */
 operator.necity = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-14;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "ne-select-city"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("ne-select-city\\(","ig"),"").replace(")","").getJsonArrParams();
             var isEq = false;
             if(params && params.length == 2) {
                 var lftValArr = eval(eval(params[0]) || "[]");
                 var rgtValArr = eval(eval(params[1]) || "[]");
                 if(!lftValArr && !rgtValArr) isEq = true;
                 else{
                     if(lftValArr && rgtValArr){
                         if(lftValArr.length == rgtValArr.length){
                             if(lftValArr.length == 0) isEq = true;
                             else{
                                 var leftCodes = [],rightCodes = [];
                                 lftValArr.forEach(function(item){
                                     if(item.CityEN) leftCodes.push(item.CityEN.toLowerCase());
                                 });
                                 rgtValArr.forEach(function(item){
                                     if(item.CityEN) rightCodes.push(item.CityEN.toLowerCase());
                                 });
                                 var leftNotInRight = leftCodes.length,rightNotInleft = rightCodes.length;
                                 leftCodes.forEach(function(code){
                                     if(rightCodes.indexOf(code) != -1) leftNotInRight --;
                                 });
                                 rightCodes.forEach(function(code){
                                     if(leftCodes.indexOf(code) != -1) rightNotInleft --;
                                 });
                                 if(leftNotInRight == 0 && rightNotInleft == 0){
                                     isEq = true;
                                 }
                             }
                         }
                     }
                 }
             }
             var result = !isEq;
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NECITY = operator.necity;
 
 //*** 城市为空 */
 operator.isnullcity = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-16;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "null-select-city"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             // if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("null-select-city\\(","ig"),"").replace(")","").getParams();
             var result = false;
             var val = common.noQuot(params[0]);
             if(typeof val === "undefined" || val === null || val.toString() === "" || val.toString() ==='' || val.toString() === '[]'){
                 result = true;
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.ISNULLCITY = operator.isnullcity;
 
 //*** 城市不为空 */
 operator.notnullcity = (function(){
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-20;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "not-null-select-city"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
 
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1) return new operator.calculateUnit(false,s_replacer);
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("not-null-select-city\\(","ig"),"").replace(")","").getParams();
             var result = false;
             var val = common.noQuot(params[0]);
             if(typeof val !== "undefined" && val !== null && val.toString() !== "" && val.toString() !=='' && val.toString() !== '[]'){
                 result = true;
             }
             
             return new operator.calculateUnit(result,s_replacer);
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.NOTNULLCITY = operator.notnullcity;
 
 /** 金额转换方法 CNMoney*/
 operator.cnmoney = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-7;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "cnmoney"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         var oprChain = operator.createArray();
         // 运算表达式适配括号
         var exp = function (val){
             var charo = 0
             var itemdata = []
             var strdata = val.split("")
             // 判断下最后一位是不是数字或者括号，不是的话删掉 
             if(strdata.length > 0){
                 var lastNum = strdata[strdata.length-1]
                 if(!common.isNumber(lastNum)){
                     if(lastNum != ')'){
                         strdata.pop()
                     }
                 }
             }
             for(var i=0;i<strdata.length;i++){
                 itemdata.push(strdata[i])
                 if((strdata[i] && strdata[i] != '.') && (strdata[i+1] && strdata[i+1] != '.')){
                     if(isNaN(strdata[i]) && isNaN(strdata[i+1])){
                         itemdata.push('(')
                         charo = charo + 1
                     }
                     if(!isNaN(strdata[i]) && isNaN(strdata[i+1]) && charo>0 ){
                         for(var n=0;n<charo;n++){
                             itemdata.push(')')
                         }
                         charo = 0
                     }
                 }
                 if((i+1 == strdata.length) && charo>0){
                     for(var n=0;n<charo;n++){
                         itemdata.push(')')
                     }
                     charo = 0
                 } 
             }
             return itemdata.join().replace(/,/g, "")
             
         }
         var evil = function(fn) { // 替代eval，计算表达式
             var Fn = Function;
             return new Fn('return ' + fn)();
         }
         var calculate = function(resultCache,resultCall){
             oprChain.setChainTag(s_replacer,"return_type",'string');
             var calculate_expression = common.fullReplace(s_expression,resultCache);
             // var argsString = calculate_expression.match(/(?<=\().*(?=\))/)[0];
             var argsString = common.noParenthesis(calculate_expression);
             if(argsString.indexOf('__ISNUMBER__') != -1){
                 argsString = argsString.replace(/__ISNUMBER__|__ROUND__/g,'');
             }
             var rtnStr = argsString;
             if(argsString == '' || argsString == null || argsString == 'undefined') {
                 return new operator.calculateUnit('零元整',s_replacer);
             }
             try {
                 argsString = common.allReplace(argsString,"''","0");
                 argsString = evil(exp(argsString))
                 rtnStr = common.convertCurrency(argsString)
                 return new operator.calculateUnit(rtnStr,s_replacer);
             } catch (error) {
                 if(rtnStr == "''" || rtnStr=='' || rtnStr == null || rtnStr == 'undefined') {
                     return new operator.calculateUnit('零元整',s_replacer);   
                 } else if (rtnStr > 999999999999) {
                     return new operator.calculateUnit('',s_replacer);
                 } else {
                     return new operator.calculateUnit(rtnStr,s_replacer);
                 }
             }
             
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer,
             setOperatorChain:function(opc){oprChain = opc;}
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.CNMONEY = operator.cnmoney;
 
 /** round 函数*/
 operator.round = (function(){
     
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-5;
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "round"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         var oprChain = operator.createArray();
     
         var calculate = function(resultCache,resultCall){
             
             var calculate_expression = common.fullReplace(s_expression,resultCache);
             // var argsString = calculate_expression.match(/(?<=\().*(?=\))/)[0];
             var argsString = common.noParenthesis(calculate_expression);
             var rtnStr = argsString
             if(argsString == '' || argsString == null || argsString == 'undefined') {
                 return new operator.calculateUnit('',s_replacer);
             }
             try {
                 rtnStr = common.roundNum(argsString)
                 oprChain.setChainTag(s_replacer,"return_type",'round-'+argsString.split(",")[1]);
                 if(!rtnStr){
                     return new operator.calculateUnit('',s_replacer);
                 }
                 rtnStr = '__ISNUMBER____ROUND__' + rtnStr;
                 return new operator.calculateUnit(rtnStr,s_replacer);
             } catch (error) {
                 if(rtnStr == "''" || rtnStr=='' || rtnStr == null || rtnStr == 'undefined') {
                     return new operator.calculateUnit('',s_replacer);   
                 } else {
                     rtnStr = '__ISNUMBER____ROUND__' + rtnStr;
                     return new operator.calculateUnit(rtnStr,s_replacer);
                 }
             }
             
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer,
             setOperatorChain:function(opc){oprChain = opc;}
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator.ROUND = operator.round;
 
 /** if 函数*/
 operator['if'] = (function(){
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-2;
         
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "if"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         var oprChain = operator.createArray();
         var calculate = function(resultCache,resultCall){
             var calculate_expression = common.fullReplace(s_expression,resultCache);
             // var argsString = calculate_expression.match(/(?<=\().*(?=\))/)[0];
             var argsString = common.noParenthesis(calculate_expression,true);
             var rtnStr = argsString
             
             if(argsString == '' || argsString == null || argsString == 'undefined') {
                 return new operator.calculateUnit('',s_replacer);
             }
             try {
                 rtnStr = common.getIF(argsString)
                 if(typeof rtnStr == 'string' && rtnStr.indexOf('__ROUND__') != -1){
                     rtnStr = rtnStr.replace(/[__ROUND__|']/g,'');
                     oprChain.setChainTag(s_replacer,"return_type",'round-'+rtnStr.split(".")[1].length);
                 }
                 if(!rtnStr){
                     return new operator.calculateUnit('',s_replacer);
                 }
                 return new operator.calculateUnit(rtnStr,s_replacer);
             } catch (error) {
                 if(rtnStr == "''" || rtnStr=='' || rtnStr == null || rtnStr == 'undefined') {
                     return new operator.calculateUnit('',s_replacer);   
                 } else {
                     return new operator.calculateUnit(rtnStr,s_replacer);
                 }
             }
             
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer,
             setOperatorChain:function(opc){oprChain = opc;}
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator['IF'] = operator['if'];
 
 /** if 函数*/
 operator['datediff'] = (function(){
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         var i_start = i-8;
         
         if(i_start<0) return null;
         if(stack.slice(i_start,i).join("").toLowerCase() == "datediff"){
             var arr = stack.slice(i_start);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
 
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         var oprChain = operator.createArray();
         var calculate = function(resultCache,resultCall){
             var calculate_expression = common.fullReplace(s_expression,resultCache);
             // var argsString = calculate_expression.match(/(?<=\().*(?=\))/)[0];
             var argsString = common.noParenthesis(calculate_expression,true);
             var rtnStr = argsString
             
             if(argsString == '' || argsString == null || argsString == 'undefined') {
                 return new operator.calculateUnit('',s_replacer);
             }
             try {
                 rtnStr = common.getDateDiff(argsString);
                 if(typeof rtnStr == 'string' && rtnStr.indexOf('__ROUND__') != -1){
                     rtnStr = rtnStr.replace(/[__ROUND__|']/g,'');
                     oprChain.setChainTag(s_replacer,"return_type",'round-'+rtnStr.split(".")[1].length);
                 }
                 if(!rtnStr && rtnStr !== 0){
                     return new operator.calculateUnit('',s_replacer);
                 }
                 return new operator.calculateUnit(rtnStr,s_replacer);
             } catch (error) {
                 if(rtnStr == "''" || rtnStr=='' || rtnStr == null || rtnStr == 'undefined') {
                     return new operator.calculateUnit('',s_replacer);   
                 } else {
                     return new operator.calculateUnit(rtnStr,s_replacer);
                 }
             }
             
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer,
             setOperatorChain:function(opc){oprChain = opc;}
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 operator['DATEDIFF'] = operator['datediff'];
 
 //*** 最小值 */
 operator.min = (function(){
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         if(i-3<0) return null;
         if(stack.slice(i-3,i).join("").toLowerCase() == "min"){
             var arr = stack.slice(i-3);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
     
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         // 找出小数位数
         var calculate = function(resultCache){
             if(s_expression.indexOf(common.unknownValue())>-1){
                 s_expression = common.allReplace(s_expression,"_unknown_value_","0");
             }
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("min\\(","ig"),"").replace(")","").getParams();
             // 异常处理
             try {
                 var sum = [];
                 for(var i = 0;i<params.length;i++){
                     var p = params[i];
                     if(typeof p == 'string' && p.indexOf('__ISNUMBER__') != -1){
                         p = Number(p.replace(/__ISNUMBER__|__ROUND__/g,'')) || 0;
                     }
                     if(p!="''" && p!=null && p!="" && p!="undefined"){
                         if(common.isNumber(p)){
                             sum.push(Number(p));
                         } else {
                             // sum = sum + arithmetic.calculate(p) *1 此方法处理不了带空字符的表达式
                             if(p!="_unknown_value_"){
                                 sum.push(arithmetic.calculate(p)*1);
                             }
                         }
                     } else if(p=="''" || p == 0){
                         sum.push(0); 
                     }
                 }
                 var min = Math.min.apply(null,sum);    //获取最小值
                 if(common.isNumber(min) || common.isScience(min)){// 判断是否为数字&科学计数法
                     min = '__ISNUMBER__' + min;
                     return new operator.calculateUnit(min,s_replacer);
                 } else {
                     return new operator.calculateUnit("",s_replacer);
                 }
                 
             } catch (error) {
                 return new operator.calculateUnit(0,s_replacer);
             }
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 //符号大小写兼容
 operator.MIN = operator.min;
 
 //*** 最小值 */
 operator.max = (function(){
     var match = function(stack){
         if(stack.length == 0) return null;
         if(stack[stack.length-1] != ")") return null;
         var i = common.findForward(stack,"(");
         if(i-3<0) return null;
         if(stack.slice(i-3,i).join("").toLowerCase() == "max"){
             var arr = stack.slice(i-3);
             return new operator.matchResult(arr);
         }else{
             return null;
         }
     };  
     
     var _class = function(matchString,replacer){
         var s_expression = matchString;
         var s_replacer = replacer;
         // 找出小数位数
         // var selectNum = function(val){
         //     var arr = val.split('.')
         //     var numlength = 0 // 记录小数位数
         //     for(var i=0;i<arr.length;i++){
         //         var num = arr[i].replace(new RegExp("\\/.*|\\*.*|\\+.*|\\-.*|\\(.*|\\).*","g"),"").length
         //         if(num>numlength){
         //             numlength = num
         //         }
         //     }
         //     return numlength
         // }
         var calculate = function(resultCache){
             var calculate_expression =  common.fullReplace(s_expression,resultCache);
             var params = calculate_expression.replace(new RegExp("max\\(","ig"),"").replace(")","").getParams();
             // 异常处理
             try {
                 var sum = [];
                 for(var i = 0;i<params.length;i++){
                     var p = params[i];
                     if(typeof p == 'string' && p.indexOf('__ISNUMBER__') != -1){
                         p = Number(p.replace(/__ISNUMBER__|__ROUND__/g,'')) || 0;
                     }
                     if(p!="''" && p!=null && p!="" && p!="undefined"){
                         if(common.isNumber(p)){
                             sum.push(Number(p));
                         } else {
                             sum.push(arithmetic.calculate(p)*1);
                         }
                     } else if(p=="''" || p == 0){
                         sum.push(0); 
                     }
                 }
                 var max = Math.max.apply(null,sum);    //获取最小值
                 if(common.isNumber(max) || common.isScience(max)){// 判断是否为数字&科学计数法
                     max = '__ISNUMBER__' + max;
                     return new operator.calculateUnit(max,s_replacer);
                 } else {
                     return new operator.calculateUnit("",s_replacer);
                 }
                 
             } catch (error) {
                 return new operator.calculateUnit(0,s_replacer);
             }
         };
         return {
             calculate:calculate,
             expression:s_expression,
             replacer:s_replacer
         };
     };
 
     return{
         match:match,
         _class:_class
     };
 })();
 //符号大小写兼容
 operator.MAX = operator.max;
/**
 * operator - end
 */

calculateExpression.operator = operator;

/*parser start */
var parser = function(){
    var self = calculateExpression;
    //获取表达式里面所有涉及到的字段
    var getFields = function(expressionString){
        var data = {main:[],children:{},sys:[]};
        //* var child = {tableCode:[field1,field2...]}; */
        var regex = /\[(.+?)\]/g;
        var arr = expressionString.match(regex);
        arr = arr?arr:[];
        for(var i=0;i<arr.length;i++){
            var item = arr[i].replace("[","").replace("]","");
            var splits = item.split(".");
            if(splits.length == 0) continue;
            if(splits.length == 2 && splits[0] == "main"){
                data.main.push(splits[1]);
            }
            if(splits.length == 2 && splits[0] == "sys"){
                data.sys.push(splits[1]);
            }
            if(splits.length == 3 && splits[0] == "children"){
                var tableCode = splits[1];
                var fieldCode = splits[2];
                if(!data.children[tableCode]) data.children[tableCode] = [];
                data.children[tableCode].push(fieldCode);
            }
        }
        return data;
    };

    //根据实际值替换表达式里的占位符
    var replaceFields = function(expression,fields,ffData,calculator_inline){
        var exp = expression.replace(/不包含/g,'⊉').replace(/包含/g,'⊇');;
        var arr = [];
        if(exp.indexOf('__ISNUMBER__') == -1){
            exp = exp.replace(/IF\s*\(\s*(-?\d+(\.\d+)?)\s*,/g,'IF(__ISNUMBER__$1,');
        }
        var isOnlyForPlanSystem = false;
        if(expression.indexOf('onlyForPlanSystem')>-1){
            isOnlyForPlanSystem = true
        }
        for(var imf = 0;imf<fields.main.length;imf++){
            var mfCode = fields.main[imf];
            var mfValue = ffData.main[mfCode];
            if(mfValue === null) mfValue = "";
            if(typeof mfValue === "undefined") mfValue = common.unknownValue();
            var placeholder = "\\[main."+mfCode+"\\]";

            var replacer = common.isNumber(mfValue)?mfValue:"'"+mfValue+"'";
            //数值字段转换一下
            if(ffData.numberFiled && ffData.numberFiled.main[mfCode]){
                replacer = '__ISNUMBER__' + replacer
            }
            if(common.isNumber(replacer)){
            }else{
                replacer = replacer.replace("(","$#leftbracket$#").replace(")","$#rightbracket$#") //把取值数据中的"("进行替换，避免参与公式计算
            }
            exp = exp.replace(/ne\((.*?)\)/g, function (all, field_label) {
                field_label = String(field_label).replace("(","$#leftbracket$#").replace(")","$#rightbracket$#")
                return "ne("+field_label+")";
            })
            exp = exp.replace(new RegExp(placeholder,"g"),replacer);
        }
        if(fields.sys){
            for(var j = 0;j<fields.sys.length;j++){
                var sysCode = fields.sys[j];
                var sysValue = ffData.sys[sysCode];
                if(sysValue === null) mfValue = "";
                if(typeof sysValue === "undefined") sysValue = common.unknownValue();
                var placeholder = "\\[sys."+sysCode+"\\]";
                var replacer = common.isNumber(sysValue)?sysValue:"'"+sysValue+"'";
                if(common.isNumber(replacer)){
                }else{
                    replacer = replacer.replace("(","$#leftbracket$#").replace(")","$#rightbracket$#") //把取值数据中的"("进行替换，避免参与公式计算
                }
                exp = exp.replace(/ne\((.*?)\)/g, function (all, field_label) {
                    field_label = String(field_label).replace("(","$#leftbracket$#").replace(")","$#rightbracket$#")
                    return "ne("+field_label+")";
                })
                exp = exp.replace(new RegExp(placeholder,"g"),replacer);//需要解决流水号为00开头的问题，比如0015实际为13
            }
        }
        if(typeof calculator_inline == "object" && calculator_inline != null && exp.indexOf(calculator_inline.table_code)>-1){
            var tbCode = calculator_inline.table_code;
            var row_i = calculator_inline.row_i;
            if(fields.children[tbCode] && (row_i!=-1 || isOnlyForPlanSystem)){
                for(var icf=0;icf<fields.children[tbCode].length;icf++){
                    var cfCode = fields.children[tbCode][icf];
                    var cfValue = ffData.children[tbCode][row_i] && ffData.children[tbCode][row_i][cfCode];
                    if(cfValue === null) cfValue = "";
                    if(typeof cfValue === "undefined") {
                        cfValue = common.unknownValue();
                    }
                    var placeholder = "\\[children."+tbCode+"."+cfCode+"\\]";
                    if(isOnlyForPlanSystem){
                        arr.push("[children."+tbCode+"."+cfCode+"]")
                    }
                    var replacer = common.isNumber(cfValue)?cfValue:"'"+cfValue+"'";
                    
                    //数值字段转换一下
                    if(ffData.numberFiled && ffData.numberFiled.children[tbCode] && ffData.numberFiled.children[tbCode][cfCode]){
                        replacer = '__ISNUMBER__' + replacer
                    }
                    if(common.isNumber(replacer)){
                    }else{
                        replacer = replacer.replace("(","$#leftbracket$#").replace(")","$#rightbracket$#") //把取值数据中的"("进行替换，避免参与公式计算
                    }
                    exp = exp.replace(new RegExp(placeholder,"g"),replacer);
                }
            }
        }else{
            for(var tbCode in fields.children){
                for(var icf = 0;icf<fields.children[tbCode].length;icf++){
                    var listData = ffData.children[tbCode];
                    var cfCode = fields.children[tbCode][icf];
                    var cfValue = [];//明细列表的字段值有多个，所以是数组，替换进表达式里是以逗号分隔形式表示
                    for(var il = 0;il<listData.length;il++){
                        var rowData = listData[il];
                        cfValue.push(rowData[cfCode]);
                    }
                    var placeholder = "\\[children."+tbCode+"."+cfCode+"\\]";
                    var replacer = "['"+cfValue.join(",")+"']"; // 值以逗号分隔形式表示
                    if(isOnlyForPlanSystem){
                        arr.push("[children."+tbCode+"."+cfCode+"]")
                    }
                    if(cfValue.length == 0) replacer = common.unknownValue();
                    if(common.isNumber(replacer)){
                    }else{
                        replacer = replacer.replace("(","$#leftbracket$#").replace(")","$#rightbracket$#") //把取值数据中的"("进行替换，避免参与公式计算
                    }
                    exp = exp.replace(new RegExp(placeholder,"g"),replacer);
                }
            }
        }
        self.operator.apievalObj.expression = arr
        if(!self.operator.cacheExpressionVal.hasOwnProperty(exp) && expression.indexOf('[sys.')==-1){
            self.operator.cacheExpressionVal[exp] = undefined;
        }
        return exp;
    };

    function whileExpression(exp,text,fields,ffData) {
        var regObj = {
            SUM:/(?:SUM\()([^\(\)]+)\)/g,
            MAX:/(?:MAX\()([^\(\)]+)\)/g,
            MIN:/(?:MIN\()([^\(\)]+)\)/g

        }
        var matchArr = exp.match(regObj[text]);
        if (matchArr && matchArr.length) {
            exp = exp.replace(regObj[text], function (all, field_label) {
                field_label = childrenReplace(fields,field_label,ffData);
                return "#"+text+"#"+"("+ field_label +")";
            })
            whileExpression(exp,text,fields,ffData);
        }
        return exp;
    }
    

    //根据实际值替换表达式里的占位符-sum
    var sumReplaceFields = function(expression,fields,ffData,calculator_inline){
        var exp = expression;
        if(exp.indexOf('__ISNUMBER__') == -1){
            exp = exp.replace(/IF\s*\(\s*(-?\d+(\.\d+)?)\s*,/g,'IF(__ISNUMBER__$1,');
        }
        for(var imf = 0;imf<fields.main.length;imf++){
            var mfCode = fields.main[imf];
            var mfValue = ffData.main[mfCode];
            if(mfValue === null) mfValue = "";
            if(typeof mfValue === "undefined") mfValue = common.unknownValue();
            var placeholder = "\\[main."+mfCode+"\\]";
            var replacer = common.isNumber(mfValue)?mfValue:"'"+mfValue+"'";

            //数值字段转换一下
            if(ffData.numberFiled && ffData.numberFiled.main[mfCode]){
                replacer = '__ISNUMBER__' + replacer
            }

            exp = exp.replace(new RegExp(placeholder,"g"),replacer);
        }
        exp = whileExpression(String(exp),'SUM',fields,ffData);
        exp = whileExpression(String(exp),'MAX',fields,ffData);
        exp = whileExpression(String(exp),'MIN',fields,ffData);
        if(typeof exp == "string"){
            exp = exp.replace(/#SUM#/g,"SUM").replace(/#MAX#/g,"MAX").replace(/#MIN#/g,"MIN");
        }
        exp = replaceFields(exp,fields,ffData,calculator_inline);
        if(!self.operator.cacheExpressionVal.hasOwnProperty(exp)){
            self.operator.cacheExpressionVal[exp] = undefined;
        }
        return exp;
    };

    var childrenReplace = function (fields,field_label,ffData){
        for(var tbCode in fields.children){
            for(var icf = 0;icf<fields.children[tbCode].length;icf++){
                var listData = ffData.children[tbCode];
                var cfCode = fields.children[tbCode][icf];
                var cfValue = [];//明细列表的字段值有多个，所以是数组，替换进表达式里是以逗号分隔形式表示
                for(var il = 0;il<listData.length;il++){
                    var rowData = listData[il];
                    cfValue.push(rowData[cfCode]);
                }
                var placeholder = "\\[children."+tbCode+"."+cfCode+"\\]";
                // 碰到子表数据需要 乘 除 加 减，需要额外加个SUM
                // var replacer = "SUM("+cfValue.join(",")+")" // cfValue.join(","); //值以逗号分隔形式表示
                var replacer = cfValue.join(",");
                if(cfValue.length == 0) replacer = 0
                field_label = field_label.replace(new RegExp(placeholder,"g"),replacer);
            }
        }
        return field_label;
    }


    var contains = function(expression,fullCode){
        var fields = getFields(expression);
        var isMain = fullCode.indexOf("main.")==0;
        var arr = fullCode.split(".");
        if(arr.length!=2 && arr.length!=3) return false;        
        if(isMain){
            var code = arr[1];
            return fields.main.indexOf(code)>-1;
        }else{
            var tbcode = arr[1];
            var fcode = arr[2];
            if(fcode){
                return typeof fields.children[tbcode] != "undefined" 
                && fields.children[tbcode].indexOf(fcode)>-1;
            } else{
                return typeof fields.children[tbcode] != "undefined"
            }

        }
    };

    //获取表达式所涉及到的表
    var involves = function(expression){
        var fields = getFields(expression);
        var tables = [];
        for(var tcode in fields.children){
            if(tables.indexOf(tcode) == -1)
                tables.push(tcode);
        }
        if(fields.main.length>0){
            tables.push("main");
        }
        return tables;
    };

    //calculator_inline有值时，则执行行内计算，否则执行列汇总计算
    //根据公式获得实际的值
    var parse = function(expression,ffData,calculator_inline){
        // expression = preParse(expression);
        var fields = getFields(expression);

        // 针对SUM函数进行处理
        if(expression.indexOf("SUM") != -1 
        || expression.indexOf("sum") != -1
        || expression.indexOf("min") != -1
        || expression.indexOf("MIN") != -1
        || expression.indexOf("max") != -1
        || expression.indexOf("MAX") != -1
    ){
            var exp_after_parse = sumReplaceFields(expression,fields,ffData,calculator_inline);
        } else {
            var exp_after_parse = replaceFields(expression,fields,ffData,calculator_inline);
        }
        return exp_after_parse;
    };

    var resetExpressionCache = function(){
        setTimeout(function(){
            self.operator.cacheExpressionVal = {};
        },300);
    }

    var expressionCache = function(){
        self.operator.cacheExpressionVal = {}
    }
   
    return{
        parse:parse,
        contains:contains,
        resetExpressionCache: resetExpressionCache,
        expressionCache: expressionCache,
        involves:involves
    };

}();

// 最终结果保留保留4位小数
var fourNum = function (num){
    if(isNumber(num)){
        // 最终结果保留4位小数
        var count = String(num).length 
        var numcount = String(num).indexOf(".") + 1; //获取小数点后的个数
        if(numcount > 0 && ((count-numcount)>4)){
            num = fomatFloat(num,4)
        }
        return num
    }
    return num
}

// 判断是否为数字  
var isNumber = function(val){
    if (parseFloat(val).toString() === "NaN") {
    　　return false; 
    }else{
        var arr = val.toString().split("");
        if(arr.length == 0) return false;
        if(arr[0] === "." || arr[arr.length-1] === ".") return false;
        var dotCount = 0;
        for(var i=0;i<arr.length;i++){
            if(arr[i] === "."){
                dotCount++;
                continue;
            }
            if(i==0 && arr[i]==="-"){
                continue;
            }
            if(parseFloat(arr[i]).toString() === "NaN") 
                return false;
                
        }
        if(dotCount>1) return false;
    　　　　 return true; 
    }
};

var getIscalculate = function(expression){
    // var exclude = ["sum","apieval"]
    // onlyforplansystem才需要关联字段发生改变才请求
    var exclude = ["sum","onlyforplansystem","min","max"]
    var str = expression.toLowerCase()
    var isCalculate = false;
    for(var i=0;i<exclude.length;i++){
        if(str.indexOf(exclude[i]) > -1){
            isCalculate = true;
        }
    }
    return !isCalculate
}

var containsSettingsExps = function(rules,settings,fullCode){
    var containsExp = false;
    settings.forEach(function(setting){
        var formula = setting.id;
        var ori_expression = calculateExpression.converter.ruleToExpression(rules,formula);
        if(calculateExpression.parser.contains(ori_expression,fullCode)) containsExp = true;
    });
    return containsExp;
};

var getSettingCount = function(settings){
    var counts = {};
    settings.forEach(function(setting){
        if(!counts[setting.target]) counts[setting.target] = 0;
        counts[setting.target]++;
    });
    return counts;
};

// 四舍五入保留两位小数 num金额 n小数位
var fomatFloat = function (num,n){   
    var isCnInfu = false
    var f = parseFloat(num);
    // 判断是否为负数
    if (num < 0) {
        // 转正整数
        num = Math.abs(num)
        isCnInfu = true
    } 
    n = parseInt(n)
    if(isNaN(f)){
        return false;
    }   
    f = Math.round(num*Math.pow(10, n))/Math.pow(10, n); // n 幂  
    if(n < 0){
        var s = f.toString();
        return isCnInfu ? '-'+s : s+'';
    } else {
        var s = f.toString();
        var rs = s.indexOf('.');
        //判定如果是整数，增加小数点再补0
        if(rs < 0 && n > 0){
            rs = s.length;
            s += '.'; 
        }
        while(s.length <= rs + n){
            s += '0';
        }
        return isCnInfu ? '-'+s : s+'';
    }
}
/*parser end */
calculateExpression.parser = parser;

/*converter.js start */
calculateExpression.converter = (function(){

    //指定的规则转换成运算表达式
    var ruleToExpression = function(rules,idFormula,ff_data,buobj){
        if(!idFormula)return '';
        var ruleIdArr = idFormula.split(" ");
        var resultArr = [];
        
        for(var i = 0;i<ruleIdArr.length;i++){
            var ruleId = ruleIdArr[i];
            if(ruleId === "") continue;
            if(ruleId.toUpperCase() === "AND" || ruleId.toUpperCase() === "OR"){
                resultArr.push(ruleId);
                continue;
            }
            var id = common.trim(ruleIdArr[i]);
            var mainRule = getRule(id,rules);
            if(mainRule === null) return "";
            var subRule = mainRule.rule;
            var formula = subRule.formula;
            //如果公式为空字符串，则默认是对每个条件进行AND连接
            if(formula == ""){
                var arr = [];
                subRule.conditions.forEach(function(cond,index){
                    arr.push(index+1);
                });
                formula = arr.join(" AND ");
            }
            if(common.isNumber(formula)){
                var fmlaArr = [formula];
            } else{
                var fmlaArr = formula.split("");
            }
            for(var ifmla = 0;ifmla<fmlaArr.length;ifmla++){
                var char = fmlaArr[ifmla];
                if(common.isNumber(char) && common.isNumber(fmlaArr[ifmla+1])){
                    char = fmlaArr[ifmla]+fmlaArr[ifmla+1];
                    fmlaArr.splice([ifmla+1],1);
                }
                if(common.isNumber(char)){
                    var condIndex = char*1;
                    if(condIndex-1 < subRule.conditions.length && condIndex-1 >= 0){
                        var cond = subRule.conditions[condIndex-1]; 
                        // 业务规则 处理逻辑
                        if(cond.mode=="business_rule" && ff_data){
                            var ori_expression =  getExpressionFromCondition(cond);
                            // 当业务规则中的 sum max min 函数，出现取不到值的情况，直接这条规则返回 false
                            if(/SUM\((.*?)\)|MAX\((.*?)\)|MIN\((.*?)\)/.test(ori_expression)){
                                var Expression  = parser.parse(ori_expression,ff_data);
                                if(Expression.indexOf(common.unknownValue())>-1){
                                    fmlaArr[ifmla] = false;
                                } else{
                                    fmlaArr[ifmla] = ori_expression;
                                }
                            } else {
                                fmlaArr[ifmla] = ori_expression;
                            }
                            
                        } else if(cond.mode=="business_object" || cond.operator){
                             // 业务对象 处理逻辑
                            var ori_expression =  getExpressionFromCondition(cond);
                            var containSub = calculateExpression.isExpressionContainSubTable(ori_expression);
                             // 当业务对象，初始化进行作用域范围判断时，不符合条件直接这条规则返回 false
                            if(buobj && buobj.type == "init" && containSub){
                                if(isExpressionValid(ori_expression,buobj.tb_code) === false){
                                    fmlaArr[ifmla] = false;
                                } else{
                                    fmlaArr[ifmla] = ori_expression;
                                }
                            } else if (buobj && buobj.type == "Event" && containSub){
                                if(buobj.row_flag !== buobj.e_flag){
                                    fmlaArr[ifmla] = false;
                                }else{
                                    fmlaArr[ifmla] = ori_expression;
                                }
                            } else {
                                fmlaArr[ifmla] = ori_expression;
                            }
                        } else {
                            fmlaArr[ifmla] = getExpressionFromCondition(cond);
                        }
                    }
                }
            }
            if(ruleIdArr.length > 1){
                resultArr.push('('+fmlaArr.join("")+')');
            }else{
                resultArr.push(fmlaArr.join(""));
            }
        }
        var s = resultArr.join(" ");
        return common.fullReplace(s,{" AND ":" && "," OR ":" || "});
    }; 

    var getExpressionFromCondition = function(condition){
        if(condition.expression){return condition.expression};
        var exprs = "";
        var code = condition.code;
        var op = condition.operator;
        var val = condition.value;
        var valType = condition.type;
        code = code.indexOf(".") == -1 ? "[main." + code + "]" : "[children." + code + "]";
        if (condition.value_type == 'column_value') {
            val = val.indexOf(".") == -1 ? "[main." + val + "]" : "[children." + val + "]";
        } else {
            if (valType === "string" || !common.isNumber(val)) {
                val = "'" + val + "'";
            }
        }
        exprs = op+"("+code+","+val+")";
        return exprs;
    }
    var getRule = function(id,rules){
        for(var irule = 0;irule<rules.length;irule++){
            var rule = rules[irule];
            if(rule.id === id)
                return rule;
        }
        return null;
    };

    return{
        ruleToExpression:ruleToExpression,
        getRule:getRule
    };

})();

export default calculateExpression

export {
    operator
}